home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1993 / 5 / 04b / funktionsplotter / fplotter.ampk / Renderer / TXT / Render.mod < prev   
Encoding:
Text File  |  1995-06-01  |  17.2 KB  |  648 lines

  1. |##########|
  2. |#MAGIC   #|BOPDNOJA
  3. |#PROJECT #|"FunctionPlotter"
  4. |#PATHS   #|"EGSProject"
  5. |#FLAGS   #|xx---x--x---x-x-----------------
  6. |#USERSW  #|--------------------------------
  7. |#USERMASK#|--------------------------------
  8. |#SWITCHES#|x----x----------
  9. |##########|
  10. IMPLEMENTATION MODULE Render;
  11.  
  12. FROM EGS             IMPORT CLUEntry;
  13. FROM EGSGfx    AS G  IMPORT RastPortPtr;
  14. FROM EGSBlit         IMPORT ClipRect,WritePixel;
  15. FROM EGSGadBox       IMPORT ResBox;
  16.                      IMPORT EGSIntui AS I;
  17. FROM OFunctions      IMPORT Function;
  18. FROM VectorLongreal  IMPORT All;
  19.  
  20. PROCEDURE CheckFunction(REF str : STRING):INTEGER;
  21. BEGIN
  22.   RETURN OFunctions.CheckFunction(str,"x","y");
  23. END CheckFunction;
  24.  
  25. TYPE
  26.   ConvParams = RECORD
  27.                  rotateNScale : Matrix;
  28.                  add          : Vector;
  29.                  dz           : LONGREAL;
  30.                  x,y          : INTEGER;
  31.                  light        : Vector;
  32.                END;
  33.  
  34.   LightVecsType  = ARRAY LightDirs OF Vector;
  35.  
  36. CONST
  37.   pi         = 4.*ATAN(1.);
  38.   pi180      = pi/180.;
  39.  
  40.   LightVects = LightVecsType:(( 0.0,1.0,0.0),
  41.                               ( 0.0,1.0,4.0),
  42.                               ( 2.0,1.0,4.0),
  43.                               (-2.0,1.0,4.0));
  44.  
  45.  
  46. PROCEDURE CalcConvParams(REF area : ResBox;
  47.                          REF func : FuncParams;
  48.                          REF draw : DrawParams):ConvParams;
  49. VAR m        : Matrix;
  50.     cz,sz,
  51.     cx,sx    : LONGREAL;
  52.  
  53.     mx,my,mz : LONGREAL;
  54.     d        : LONGREAL;
  55. BEGIN
  56.   cz:=COS(LONGREAL(draw.bearing)*pi180);
  57.   sz:=SIN(LONGREAL(draw.bearing)*pi180);
  58.   cx:=COS(LONGREAL(draw.pitch)*pi180);
  59.   sx:=SIN(LONGREAL(draw.pitch)*pi180);
  60.  
  61.   d:=SQRT(LONGREAL(area.w-16)^2.+LONGREAL(area.h-16)^2.)/SQRT(2.);
  62.  
  63.   mx:=d/(func.maxX-func.minX);
  64.   my:=d/(func.maxY-func.minY);
  65.   mz:=d/(func.maxZ-func.minZ);
  66.  
  67.   RESULT.add[0]:=-func.maxX/2.-func.minX/2.;
  68.   RESULT.add[1]:=-func.maxY/2.-func.minY/2.;
  69.   RESULT.add[2]:=-func.maxZ/2.-func.minZ/2.;
  70.  
  71.   WITH RESULT.rotateNScale AS m DO
  72.     m[0,0]:= mx*cz;
  73.     m[0,1]:= mx*sz*cx;
  74.     m[0,2]:=-mx*sz*sx;
  75.  
  76.     m[1,0]:=-my*sz;
  77.     m[1,1]:= my*cz*cx;
  78.     m[1,2]:=-my*cz*sx;
  79.  
  80.     m[2,0]:= 0.0;
  81.     m[2,1]:=-mz*sx;
  82.     m[2,2]:=-mz*cx;
  83.   END;
  84.  
  85.   RESULT.dz:=2.0*SQRT(LONGREAL(area.w)^2.+LONGREAL(area.h)^2.);
  86.  
  87.   RESULT.x:=area.x+area.w DIV 2;
  88.   RESULT.y:=area.y+area.h DIV 2;
  89.  
  90.   RESULT.light:=VMMul(MInvert(RESULT.rotateNScale),LightVects[draw.light]);
  91.   VNorm(RESULT.light);
  92.  
  93. END CalcConvParams;
  94.  
  95. PROCEDURE Conv3dTo2d(REF conv : ConvParams;
  96.                      REF pos  : Vector;
  97.                      VAR x,y  : INTEGER);
  98. VAR v : Vector;
  99. BEGIN
  100.   v:=VMMul(conv.rotateNScale,VAdd(pos,conv.add));
  101.   x:=INTEGER(conv.dz*v[0]/(v[2]+conv.dz))+conv.x;
  102.   y:=INTEGER(conv.dz*v[1]/(v[2]+conv.dz))+conv.y;
  103. END Conv3dTo2d;
  104.  
  105. PROCEDURE RenderFunction(    rast  : RastPortPtr;
  106.                          REF area  : ResBox;
  107.                          REF func  : FuncParams;
  108.                          REF draw  : DrawParams;
  109.                              break : Break);
  110.  
  111.   TYPE
  112.     DrawRectProc    = PROCEDURE(v00,v01,v10,v11 : Vector);
  113.  
  114.   VAR
  115.     conv : ConvParams;
  116.  
  117.   PROCEDURE TraceIt;
  118.   VAR f               : Function;
  119.       minX,maxX,
  120.       minY,maxY,
  121.       minZ,maxZ       : LONGREAL;
  122.       rred,
  123.       rgreen,
  124.       rblue           : LONGREAL;
  125.  
  126.       revmat          : Matrix;
  127.       view,dir        : Vector;
  128.       dirx,diry,dirz  : Vector;
  129.  
  130.       x,y             : INTEGER;
  131.       color           : Vector;
  132.       r,g,b           : INTEGER;
  133.  
  134.       light           : Vector;
  135.  
  136.       DeltaRay        : LONGREAL;
  137.  
  138.     PROCEDURE CalcDxF(x,y : LONGREAL):LONGREAL;
  139.     BEGIN
  140.       RETURN (f.Eval(x+0.01,y)-f.Eval(x,y))/0.01;
  141.     END CalcDxF;
  142.  
  143.     PROCEDURE CalcDyF(x,y : LONGREAL):LONGREAL;
  144.     BEGIN
  145.       RETURN (f.Eval(x,y+0.01)-f.Eval(x,y))/0.01;
  146.     END CalcDyF;
  147.  
  148.     EXCEPTION NoCutPoint : "No cut point";
  149.  
  150.     CONST
  151.       HalfIter  =  6;
  152.  
  153.     |
  154.     | p : Stuetzpunkt
  155.     | n : Richtung (normalisiert !!!)
  156.     |
  157.     PROCEDURE IntersectRay(p,n : Vector):Vector;
  158.     VAR r            : LONGREAL;
  159.         pleft,pright : Vector;
  160.         i            : INTEGER;
  161.     BEGIN
  162.       IF p[2]>maxZ THEN
  163.         ASSERT(n[2]<0,NoCutPoint);
  164.         p[0]:=p[0]-n[0]*(p[2]-func.maxZ)/n[2];
  165.         p[1]:=p[1]-n[1]*(p[2]-func.maxZ)/n[2];
  166.         p[2]:=func.maxZ;
  167.       END;
  168.       n:=VExt(n,DeltaRay);
  169.       REPEAT
  170.         p:=VAdd(p,n);
  171.         r:=f.Eval(p[0],p[1]);
  172.       UNTIL (p[2]<r) OR (p[0]<minX) AND (n[0]<0.)
  173.                      OR (p[0]>maxX) AND (n[0]>0.)
  174.                      OR (p[1]<minY) AND (n[1]<0.)
  175.                      OR (p[1]>maxY) AND (n[1]>0.)
  176.                      OR (p[2]>maxZ) AND (n[2]>0.);
  177.       ASSERT(p[2]<r,NoCutPoint);
  178.       pleft:=VSub(p,n);
  179.       pright:=p;
  180.       FOR i:=1 TO HalfIter DO
  181.         p[0]:=(pleft[0]+pright[0])/2.0;
  182.         p[1]:=(pleft[1]+pright[1])/2.0;
  183.         p[2]:=(pleft[2]+pright[2])/2.0;
  184.         r:=f.Eval(p[0],p[1]);
  185.         IF p[2]<r THEN
  186.           pright:=p
  187.         ELSE
  188.           pleft:=p;
  189.         END;
  190.       END;
  191.       ASSERT((p[0]>=minX) AND
  192.              (p[0]<=maxX) AND
  193.              (p[1]>=minY) AND
  194.              (p[1]<=maxY) AND
  195.              (p[2]<=maxZ)       ,NoCutPoint);
  196.       RESULT[0]:=(pleft[0]+pright[0])/2.0;
  197.       RESULT[1]:=(pleft[1]+pright[1])/2.0;
  198.       RESULT[2]:=f.Eval(RESULT[0],RESULT[1]);
  199.     END IntersectRay;
  200.  
  201.     PROCEDURE CheckRay(p,n : Vector):BOOLEAN;
  202.     VAR r            : LONGREAL;
  203.         pleft,pright : Vector;
  204.         i            : INTEGER;
  205.     BEGIN
  206.       n:=VExt(n,DeltaRay);
  207.       REPEAT
  208.         p:=VAdd(p,n);
  209.         r:=f.Eval(p[0],p[1]);
  210.       UNTIL (p[2]<r) OR (p[0]<minX) OR (p[0]>maxX) OR
  211.                         (p[1]<minY) OR (p[1]>maxY) OR
  212.                         (p[2]>maxZ);
  213.       RETURN p[2]<r;
  214.     END CheckRay;
  215.  
  216.     PROCEDURE NormVector(p : Vector):Vector;
  217.     BEGIN
  218.       RESULT[0]:=-CalcDxF(p[0],p[1]);
  219.       RESULT[1]:=-CalcDyF(p[0],p[1]);
  220.       RESULT[2]:=1.0;
  221.       VNorm(RESULT);
  222.     END NormVector;
  223.  
  224.     PROCEDURE CalcLight(n : Vector):LONGREAL;
  225.     VAR r : LONGREAL;
  226.     BEGIN
  227.       r:=light[0]*n[0]+light[1]*n[1]+light[2]*n[2];
  228.       IF r<0.0 THEN
  229.         r:=0.0
  230.       END;
  231.       RETURN r;
  232.     END CalcLight;
  233.  
  234.     PROCEDURE CalcColor(p,n : Vector;depth : INTEGER := 10):Vector;
  235.     VAR hit,norm : Vector;
  236.         hit2     : Vector;
  237.         l,spec   : LONGREAL;
  238.         co,co2   : Vector;
  239.         t        : LONGREAL;
  240.     BEGIN
  241.       IF depth=0 THEN
  242.         RESULT:=Vector:(0.0,0.0,0.0)
  243.       ELSE
  244.         DEC(depth);
  245.         VNorm(n);
  246.         TRY
  247.           hit:=IntersectRay(p,n);
  248.           norm:=NormVector(hit);
  249.           l:=CalcLight(norm);
  250.           IF draw.shadows AND (l>0) THEN
  251.             IF CheckRay(hit,light) THEN
  252.               l:=0.0
  253.             END;
  254.           END;
  255.           IF draw.specular THEN
  256.             spec:=0.7*l^16.0;
  257.             l:=l*0.6+0.1;
  258.             co[0]:=l*rred+spec;
  259.             co[1]:=l*rgreen+spec;
  260.             co[2]:=l*rblue+spec;
  261.           ELSE
  262.             l:=l*0.9+0.1;
  263.             co[0]:=l*rred;
  264.             co[1]:=l*rgreen;
  265.             co[2]:=l*rblue;
  266.           END;
  267.           IF draw.mirror THEN
  268.             t:=-2.0*(n[0]*norm[0]+n[1]*norm[1]+n[2]*norm[2]);
  269.             n[0]:=n[0]+t*norm[0];
  270.             n[1]:=n[1]+t*norm[1];
  271.             n[2]:=n[2]+t*norm[2];
  272.             co2:=CalcColor(hit,n,depth);
  273.             RESULT[0]:=co[0]*0.5+co2[0]*0.6;
  274.             RESULT[1]:=co[1]*0.5+co2[1]*0.6;
  275.             RESULT[2]:=co[2]*0.5+co2[2]*0.6;
  276.           ELSE
  277.             RESULT:=co;
  278.           END;
  279.         EXCEPT
  280.           OF NoCutPoint THEN
  281.             RESULT[0]:=(1.0-n[2])*0.5;
  282.             RESULT[1]:=(1.0-n[2])*0.5;
  283.             RESULT[2]:=(1.0-n[2])*0.7;
  284.           END;
  285.         END;
  286.       END;
  287.     END CalcColor;
  288.  
  289.     PROCEDURE SQR(x : LONGREAL):LONGREAL;
  290.     BEGIN
  291.       RETURN x*x;
  292.     END SQR;
  293.  
  294.   BEGIN
  295.     minX:=func.minX;
  296.     maxX:=func.maxX;
  297.     minY:=func.minY;
  298.     maxY:=func.maxY;
  299.     minZ:=func.minZ;
  300.     maxZ:=func.maxZ;
  301.  
  302.     DeltaRay:=SQRT(SQR(maxX-minX)+SQR(maxY-minY)+SQR(maxZ-minZ))/40; |Schätzwert
  303.  
  304.     f.Create(func.funcStr,NIL,"x","y");
  305.     rred  :=LONGREAL(draw.fColor.red)/255.0;
  306.     rgreen:=LONGREAL(draw.fColor.green)/255.0;
  307.     rblue :=LONGREAL(draw.fColor.blue)/255.0;
  308.  
  309.     revmat:=MInvert(conv.rotateNScale);
  310.  
  311.     view[0]:=0.0;
  312.     view[1]:=0.0;
  313.     view[2]:=-conv.dz;
  314.     view:=VAdd(VMMul(revmat,view),conv.add);
  315.  
  316.     light:=VNeg(conv.light);
  317.  
  318.     dirz[0]:=0.0;
  319.     dirz[1]:=0.0;
  320.     dirz[2]:=conv.dz;
  321.     dirz:=VMMul(revmat,dirz);
  322.  
  323.     dirx:=VMMul(revmat,Vector:(1.0,0.0,0.0));
  324.     diry:=VMMul(revmat,Vector:(0.0,1.0,0.0));
  325.  
  326.     dirz:=VAdd(dirz,VExt(dirx,-LONGREAL(area.w DIV 2)),
  327.                     VExt(diry,-LONGREAL(area.h DIV 2)));
  328.  
  329.     FOR y:=0 TO area.h-1 DO
  330.       dir:=dirz;
  331.       IF draw.renderMap#NIL THEN
  332.         FOR x:=0 TO area.w-1 DO
  333.           color:=CalcColor(view,dir);
  334.           r:=INTEGER(color[0]*255.);IF r<0 THEN r:=0 OR_IF r>255 THEN r:=255 END;
  335.           g:=INTEGER(color[1]*255.);IF g<0 THEN g:=0 OR_IF g>255 THEN g:=255 END;
  336.           b:=INTEGER(color[2]*255.);IF b<0 THEN b:=0 OR_IF b>255 THEN b:=255 END;
  337.           WritePixel(draw.renderMap,LONGINT(r) SHL 24+
  338.                                     LONGINT(g) SHL 16+
  339.                                     LONGINT(b) SHL  8,
  340.                                     x,y,{});
  341.           dir:=VAdd(dir,dirx);
  342.         END;
  343.         G.CopyBitMapRastPort(draw.renderMap,rast,0,y,area.w,1,area.x,area.y+y);
  344.       ELSE
  345.         FOR x:=0 TO area.w-1 DO
  346.           color:=CalcColor(view,dir);
  347.           r:=INTEGER(color[0]*255.);IF r<0 THEN r:=0 OR_IF r>255 THEN r:=255 END;
  348.           g:=INTEGER(color[1]*255.);IF g<0 THEN g:=0 OR_IF g>255 THEN g:=255 END;
  349.           b:=INTEGER(color[2]*255.);IF b<0 THEN b:=0 OR_IF b>255 THEN b:=255 END;
  350.           G.SetAPen(rast,LONGINT(r) SHL 24+
  351.                          LONGINT(g) SHL 16+
  352.                          LONGINT(b) SHL  8);
  353.           G.WritePixel(rast,x+area.x,y+area.y);
  354.           dir:=VAdd(dir,dirx);
  355.         END;
  356.       END;
  357.       dirz:=VAdd(dirz,diry);
  358.       IF break() THEN
  359.         f.Delete;
  360.         RETURN
  361.       END;
  362.     END;
  363.  
  364.     f.Delete;
  365.   END TraceIt;
  366.  
  367.   PROCEDURE RenderIt(call : DrawRectProc);
  368.   VAR x,y             : INTEGER;
  369.       prevRow         : ARRAY [256] OF LONGREAL;
  370.       v00,v01,v10,v11 : Vector;
  371.       xr,yr,dx,dy,xs  : LONGREAL;
  372.       num             : INTEGER;
  373.       f               : Function;
  374.   BEGIN
  375.     f.Create(func.funcStr,NIL,"x","y");
  376.  
  377.     num:=1 SHL draw.resolution;
  378.     dy:=(func.maxY-func.minY)/LONGREAL(num);
  379.     yr:=func.minY;
  380.  
  381.     IF draw.bearing<0 THEN
  382.       dx:=(func.minX-func.maxX)/LONGREAL(num);
  383.       xs:=func.maxX;
  384.     ELSE
  385.       dx:=(func.maxX-func.minX)/LONGREAL(num);
  386.       xs:=func.minX;
  387.     END;
  388.  
  389.     xr:=xs;
  390.  
  391.     FOR x:=0 TO num DO
  392.       prevRow[x]:=f.Eval(xr,yr);
  393.       xr:=xr+dx;
  394.     END;
  395.     FOR y:=1 TO num DO
  396.       v10[1]:=yr;v11[1]:=yr;
  397.       yr:=yr+dy;
  398.       v00[1]:=yr;v01[1]:=yr;
  399.       xr:=xs;
  400.       v10[2]:=prevRow[0];
  401.       v00[2]:=f.Eval(xr,yr);
  402.       FOR x:=1 TO num DO
  403.         v00[0]:=xr;v10[0]:=xr;
  404.         xr:=xr+dx;
  405.         v01[0]:=xr;v11[0]:=xr;
  406.         v11[2]:=prevRow[x];
  407.         v01[2]:=f.Eval(xr,yr);
  408.         IF draw.bearing<0 THEN
  409.           call(v00,v10,v01,v11);
  410.         ELSE
  411.           call(v00,v01,v10,v11);
  412.         END;
  413.         prevRow[x-1]:=v00[2];
  414.         v10[2]:=v11[2];
  415.         v00[2]:=v01[2];
  416.       END;
  417.       prevRow[num]:=v00[2];
  418.       IF break() THEN
  419.         f.Delete;
  420.         RETURN
  421.       END;
  422.     END;
  423.  
  424.     f.Delete;
  425.   END RenderIt;
  426.  
  427.   PROCEDURE WireFrame(v00,v01,v10,v11 : Vector);
  428.   VAR x00,x01,x10,x11 : INTEGER;
  429.       y00,y01,y10,y11 : INTEGER;
  430.   BEGIN
  431.     Conv3dTo2d(conv,v00,x00,y00);
  432.     Conv3dTo2d(conv,v01,x01,y01);
  433.     Conv3dTo2d(conv,v10,x10,y10);
  434.     Conv3dTo2d(conv,v11,x11,y11);
  435.  
  436.     G.SetAPen(rast,0);
  437.     G.Move(rast,x00,y00);
  438.     G.Draw(rast,x01,y01);
  439.     G.Draw(rast,x11,y11);
  440.     G.Draw(rast,x10,y10);
  441.     G.Draw(rast,x00,y00);
  442.   END WireFrame;
  443.  
  444.   PROCEDURE Flat(v00,v01,v10,v11 : Vector);
  445.   VAR x00,x01,x10,x11 : INTEGER;
  446.       y00,y01,y10,y11 : INTEGER;
  447.   BEGIN
  448.     Conv3dTo2d(conv,v00,x00,y00);
  449.     Conv3dTo2d(conv,v01,x01,y01);
  450.     Conv3dTo2d(conv,v10,x10,y10);
  451.     Conv3dTo2d(conv,v11,x11,y11);
  452.  
  453.     G.SetAPen(rast,draw.fPen);
  454.     G.AreaMove(rast,x00,y00);
  455.     G.AreaDraw(rast,x01,y01);
  456.     G.AreaDraw(rast,x11,y11);
  457.     G.AreaDraw(rast,x10,y10);
  458.     G.AreaDraw(rast,x00,y00);
  459.     G.AreaEnd(rast);
  460.     IF draw.outlined THEN
  461.       G.SetAPen(rast,$00000000);
  462.       G.Move(rast,x00,y00);
  463.       G.Draw(rast,x01,y01);
  464.       G.Draw(rast,x11,y11);
  465.       G.Draw(rast,x10,y10);
  466.       G.Draw(rast,x00,y00);
  467.     END;
  468.   END Flat;
  469.  
  470.   PROCEDURE Shaded(v00,v01,v10,v11 : Vector);
  471.   VAR x00,x01,x10,x11 : INTEGER;
  472.       y00,y01,y10,y11 : INTEGER;
  473.       norm            : Vector;
  474.       light           : INTEGER;
  475.   BEGIN
  476.     Conv3dTo2d(conv,v00,x00,y00);
  477.     Conv3dTo2d(conv,v01,x01,y01);
  478.     Conv3dTo2d(conv,v10,x10,y10);
  479.     Conv3dTo2d(conv,v11,x11,y11);
  480.  
  481.     norm:=VCMul(VSub(v00,v11),VSub(v01,v10));
  482.     VNorm(norm);
  483.     light:=INTEGER(256.0*VSMul(norm,conv.light));
  484.     IF light<10 THEN light:=10
  485.     OR_IF light>256 THEN light:=256 END;
  486.     G.SetAPen(rast,LMUL(light,INTEGER(draw.fColor.red))   DIV 256 SHL 24+
  487.                    LMUL(light,INTEGER(draw.fColor.green)) DIV 256 SHL 16+
  488.                    LMUL(light,INTEGER(draw.fColor.blue))  DIV 256 SHL 8);
  489.     G.AreaMove(rast,x00,y00);
  490.     G.AreaDraw(rast,x01,y01);
  491.     G.AreaDraw(rast,x11,y11);
  492.     G.AreaDraw(rast,x10,y10);
  493.     G.AreaDraw(rast,x00,y00);
  494.     G.AreaEnd(rast);
  495.     IF draw.outlined THEN
  496.       G.SetAPen(rast,$00000000);
  497.       G.Move(rast,x00,y00);
  498.       G.Draw(rast,x01,y01);
  499.       G.Draw(rast,x11,y11);
  500.       G.Draw(rast,x10,y10);
  501.       G.Draw(rast,x00,y00);
  502.     END;
  503.   END Shaded;
  504.  
  505.   PROCEDURE Specular(v00,v01,v10,v11 : Vector);
  506.   VAR x00,x01,x10,x11 : INTEGER;
  507.       y00,y01,y10,y11 : INTEGER;
  508.       norm            : Vector;
  509.       light,spec      : LONGREAL;
  510.       red,green,blue  : LONGINT;
  511.   BEGIN
  512.     Conv3dTo2d(conv,v00,x00,y00);
  513.     Conv3dTo2d(conv,v01,x01,y01);
  514.     Conv3dTo2d(conv,v10,x10,y10);
  515.     Conv3dTo2d(conv,v11,x11,y11);
  516.  
  517.     norm:=VCMul(VSub(v00,v11),VSub(v01,v10));
  518.     VNorm(norm);
  519.     light:=VSMul(norm,conv.light);
  520.     IF light<0 THEN light:=0 END;
  521.     spec:=light^16.0*192.;
  522.     light:=light*0.9+0.1;
  523.  
  524.     red  :=LONGINT(LONGREAL(draw.fColor.red  )*light+spec);
  525.     green:=LONGINT(LONGREAL(draw.fColor.green)*light+spec);
  526.     blue :=LONGINT(LONGREAL(draw.fColor.blue )*light+spec);
  527.  
  528.     IF red  >255 THEN red  :=255 END;
  529.     IF green>255 THEN green:=255 END;
  530.     IF blue >255 THEN blue :=255 END;
  531.  
  532.  
  533.     G.SetAPen(rast,red   SHL 24+
  534.                    green SHL 16+
  535.                    blue  SHL 8);
  536.  
  537.     G.AreaMove(rast,x00,y00);
  538.     G.AreaDraw(rast,x01,y01);
  539.     G.AreaDraw(rast,x11,y11);
  540.     G.AreaDraw(rast,x10,y10);
  541.     G.AreaDraw(rast,x00,y00);
  542.     G.AreaEnd(rast);
  543.     IF draw.outlined THEN
  544.       G.SetAPen(rast,$00000000);
  545.       G.Move(rast,x00,y00);
  546.       G.Draw(rast,x01,y01);
  547.       G.Draw(rast,x11,y11);
  548.       G.Draw(rast,x10,y10);
  549.       G.Draw(rast,x00,y00);
  550.     END;
  551.   END Specular;
  552.  
  553. VAR rect : ClipRect;
  554.  
  555. BEGIN
  556.   conv:=CalcConvParams(area,func,draw);
  557.   rect.next:=NIL;
  558.   rect.left:=area.x;
  559.   rect.top :=area.y;
  560.   rect.right:=area.x+area.w-1;
  561.   rect.bottom:=area.y+area.h-1;
  562.   G.InstallClipRegion(rast,rect'PTR);
  563.   G.SetAPen(rast,draw.bPen);
  564.   G.RectangleFill(rast,area.x,area.y,area.w,area.h);
  565.   IF KEY draw.mode
  566.     OF wire      THEN RenderIt(WireFrame) END
  567.     OF solid     THEN RenderIt(Flat)      END
  568.     OF shaded    THEN
  569.                    IF draw.specular THEN
  570.                      RenderIt(Specular);
  571.                    ELSE
  572.                      RenderIt(Shaded);
  573.                    END;
  574.                  END
  575.     OF traced    THEN TraceIt END;
  576.   END;
  577.   FORGET G.RemoveClipRegion(rast);
  578. END RenderFunction;
  579.  
  580. PROCEDURE AxisMove(    rast    : RastPortPtr;
  581.                   REF area    : ResBox;
  582.                   VAR draw    : DrawParams;
  583.                       pitch   : Pitch;
  584.                       bearing : Bearing);
  585. CONST
  586.   func = FuncParams:(minX=-1,maxX=1,
  587.                      minY=-1,maxY=1,
  588.                      minZ=-1,maxZ=1);
  589.  
  590. VAR
  591.   conv : ConvParams;
  592.   midx,midy : INTEGER;
  593.   axx,axy   : INTEGER;
  594.   arx,ary   : INTEGER;
  595.   rect      : ClipRect;
  596.  
  597. BEGIN
  598.   IF (pitch#draw.pitch) OR (bearing#draw.bearing) THEN
  599.     draw.pitch:=pitch;
  600.     draw.bearing:=bearing;
  601.     conv:=CalcConvParams(area,func,draw);
  602.  
  603.     rect.next:=NIL;
  604.     rect.left:=area.x;
  605.     rect.top :=area.y;
  606.     rect.right:=area.x+area.w-1;
  607.     rect.bottom:=area.y+area.h-1;
  608.     G.InstallClipRegion(rast,rect'PTR);
  609.  
  610.     G.SetAPen(rast,draw.bPen);
  611.     G.RectangleFill(rast,area.x,area.y,area.w,area.h);
  612.     G.SetAPen(rast,$00000000);
  613.     Conv3dTo2d(conv,Vector:(0.0,0.0,0.0),midx,midy);
  614.  
  615.     Conv3dTo2d(conv,Vector:(1.0,0.0,0.0),axx,axy);
  616.     G.Move(rast,midx,midy);
  617.     G.Draw(rast,axx,axy);
  618.     Conv3dTo2d(conv,Vector:(0.9,0.1,0.0),arx,ary);
  619.     G.Draw(rast,arx,ary);
  620.     G.Move(rast,axx,axy);
  621.     Conv3dTo2d(conv,Vector:(0.9,-0.1,0.0),arx,ary);
  622.     G.Draw(rast,arx,ary);
  623.  
  624.     Conv3dTo2d(conv,Vector:(0.0,1.0,0.0),axx,axy);
  625.     G.Move(rast,midx,midy);
  626.     G.Draw(rast,axx,axy);
  627.     Conv3dTo2d(conv,Vector:(0.1,0.9,0.0),arx,ary);
  628.     G.Draw(rast,arx,ary);
  629.     G.Move(rast,axx,axy);
  630.     Conv3dTo2d(conv,Vector:(-0.1,0.9,0.0),arx,ary);
  631.     G.Draw(rast,arx,ary);
  632.  
  633.     Conv3dTo2d(conv,Vector:(0.0,0.0,1.0),axx,axy);
  634.     G.Move(rast,midx,midy);
  635.     G.Draw(rast,axx,axy);
  636.     Conv3dTo2d(conv,Vector:(0.1,0.0,0.9),arx,ary);
  637.     G.Draw(rast,arx,ary);
  638.     G.Move(rast,axx,axy);
  639.     Conv3dTo2d(conv,Vector:(-0.1,0.0,0.9),arx,ary);
  640.     G.Draw(rast,arx,ary);
  641.  
  642.     FORGET G.RemoveClipRegion(rast);
  643.   END;
  644. END AxisMove;
  645.  
  646.  
  647. END Render.
  648.